package top.pengdong.dachuang.main.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import top.pengdong.dachuang.main.filter.JwtAuthenticationTokenFilter;
import top.pengdong.dachuang.main.handle.RestfulAccessDeniedHandle;
import top.pengdong.dachuang.main.point.RestAuthorizationEntryPoint;
import top.pengdong.dachuang.main.pojo.LoginUser;
import top.pengdong.common.pojo.User;
import top.pengdong.dachuang.main.service.UserService;

import javax.annotation.Resource;

/**
 * @description:
 * @projectName: SystemServer
 * @see: com.peng.systemserver.config
 * @author: pc
 * @createTime: 2022/2/7 23:45
 * @version: 1.0
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Resource
	private UserService userService;

	@Resource
	private RestfulAccessDeniedHandle restfulAccessDeniedHandle;

	@Resource
	private RestAuthorizationEntryPoint restAuthorizationEntryPoint;

	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers(
				"/login",
				"/logout",
				"/css/*",
				"/js/**",
				"index.html",
				"favicon.ico",
				"/doc.html",
				"/webjars/**",
				"/swagger-resources/**",
				"/v2/api-docs/**"
		);
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 使用jwt，不需要crsf
		http.csrf()
				.disable()
				// 关闭session，因为基于token格式
				.sessionManagement()
				.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
				.and()
				.authorizeRequests()
				.antMatchers("/hello", "/login", "/logout","/test/**")
				.permitAll()
				.anyRequest()
				.authenticated()
				.and()
				// 关闭缓存
				.headers()
				.cacheControl();
		http.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
		http.exceptionHandling()
				.authenticationEntryPoint(restAuthorizationEntryPoint)
				.accessDeniedHandler(restfulAccessDeniedHandle);
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
	}

	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	@Override
	@Bean
	protected UserDetailsService userDetailsService() {
		return username -> {
			User user = userService.getUserByUsername(username);
			if (null != user) {
				LoginUser details = new LoginUser(user.getUsername(), user.getPassword());
				return details;
			}
			return null;
		};
	}

	@Bean
	public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
		return new JwtAuthenticationTokenFilter();
	}
}
